#ifndef db_ADAPTER_H
#define  db_ADAPTER_H

#include "Any.h"
#include "FieldMap.h"
#include <vector>
#include <string>

namespace serika
{
	namespace db
	{
		class Adapter
		{
		protected:
			Adapter();
			virtual ~Adapter();
	
		public:
			static Adapter* Create(const std::string& adapterName, const Any& initInfo);
	
			virtual bool Create(const Any& initInfo) = 0;
	
			virtual void Destroy() = 0;
	
			virtual std::string ConstructConditions(const std::string& column, const Any& value);
			virtual std::string ConstructConditions(const std::string& column, const std::vector<Any>& values);
			virtual std::string ConstructIdConditions(int id);
			virtual std::string ConstructIdConditions(const std::vector<int>& ids);
	
			virtual int ReadRecords(std::vector<FieldMap*>& resultSet,
				const std::string& tableName,
				const std::string& conditions,
				int offset,
				int limit,
				const std::string& select,
				const std::string& joins,
				const std::string& order,
				const std::string& group,
				const std::string& having) = 0;
	
			virtual int Count(const std::string& tableName, const std::string& column, const std::string& conditions, const std::string& joins) = 0;
	
			virtual bool CreateRecord(FieldMap* fields, const std::string& tableName, const std::string& primaryKey) = 0;
			virtual bool CreateRecords(std::vector<FieldMap*>& fields, const std::string& tableName, const std::string& primaryKey) = 0;
	
			virtual bool UpdateRecord(const FieldMap* fields, const std::string& tableName, const std::string& column, const Any& value);
			virtual int UpdateAllRecords(const std::string& settings, const std::string& conditions, const std::string& tableName) = 0;
	
			virtual int DeleteRecord(const std::string& conditions, const std::string& tableName) = 0;
	
			virtual void BeginTransaction() = 0;
			virtual void CommitTransaction() = 0;
			virtual void RollbackTransaction() = 0;
	
			virtual std::string EscapeString(const std::string& text) = 0;
	
			virtual std::string ConstructSelect(const std::string& tableName,
				const std::string& conditions,
				int offset,
				int limit,
				const std::string& select,
				const std::string& joins,
				const std::string& order,
				const std::string& group,
				const std::string& having);
	
			virtual std::string ConstructInsert(const FieldMap* fields, const std::string& tableName);
			virtual std::string ConstructMultipleInsert(const std::vector<FieldMap*>& fieldMapds, const std::string& tableName);

			virtual std::string ConstructUpdate(const std::string& tableName,
				const std::string& settings,
				const std::string& conditions);

			virtual std::string ConstructDelete(const std::string& tableName, const std::string& conditions);

			inline void PrepareUpdateSql(std::string& settings, 
				std::string& conditions, 
				const FieldMap* fields, 
				const std::string& tableName, 
				const std::string& column,
				const Any& value);

		protected:
		};
	}
}

#endif
